<?php
/*
 * MiniMe - a minimalistic OStatus complient microblogging tool
 * Copyright (C) 2010, Tuomas Koski - koski.tuomas@gmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * This class should represend xml similar to this:
 * <minimeuser>
 *   <username>tkoski</username>
 *   <name>Tuomas Koski</name>
 *   <uri>http://lobstermosnter.org/minime</uri>
 *   <encoded-privatekey>dfdfd</encoded-privatekey>
 *   <encoded-publickey>sdfsdfsd</encoded-publickey>
 *   <title>My timeline!</title>
 *   <subtitle>My timeline provided by minime mini system. Minimalic!</subtitle>
 *   <logo>http://media.buddycloud.com/channel/54x54/buddycloud.com/koski.png</logo>
 * </minimeuser>
 * 
 * THIS CLASS SHOULD BE REFACTORED. THERE IS TOO MUCH WORK DONE WHEN ADDING A NEW
 * CONFIGURATION PARAMETER!
 * 
 * @author     Tuomas Koski <koski.tuomas@gmail.com>
 * @copyright  Tuomas Koski
 * @license    http://www.gnu.org/licenses/lgpl.txt
 */
class Minime_User {
    
    private $uri;
    private $name;
    
    private $encodedPrivateKey;
    private $encodedPublicKey;

    private $title;
    private $subtitle;
    private $logo;
    
    private $jid;
    private $node;
    private $domain;
    
    const ELEMENT_ROOT = "minimeuser";
    const ELEMENT_URI  = "uri";
    const ELEMENT_JID  = "jid";
    const ELEMENT_NAME = "name";
    const ELEMENT_ENCODEDPUBLICKEY = "encoded-publickey";
    const ELEMENT_ENCODEDPRIVATEKEY = "encoded-privatekey";
    const ELEMENT_TITLE    = "title";
    const ELEMENT_SUBTITLE = "subtitle";
    const ELEMENT_LOGO     = "logo";
    
    private function __construct() {
        
    }
    
    public function setTitle($title) {
        if(empty($title)) {
            throw new Exception("Title cannot be set empty!");
        }
        //$this->title = htmlentities($title, ENT_QUOTES, "UTF-8", false);
        $this->title = htmlspecialchars($title, ENT_QUOTES, "UTF-8", false);
    }
    
    public function getTitle() {
        return $this->title;
    }
    
    public function setSubtitle($title) {
        //$this->subtitle = htmlentities($title, ENT_QUOTES, "UTF-8", false);
        $this->subtitle = htmlspecialchars($title, ENT_QUOTES, "UTF-8", false);
    }
    
    public function getSubtitle() {
        return $this->subtitle;
    }
    
    public function setLogo($logo) {
        //$this->logo = htmlentities($logo, ENT_QUOTES, "UTF-8", false);
        $this->logo = htmlspecialchars($logo, ENT_QUOTES, "UTF-8", false);
    }
    
    public function getLogo() {
        return $this->logo;
    }
    
    public function setUri($uri) {
        if(empty($uri)) {
            throw new Exception("URI cannot be set empty!");
        }
        $this->uri = $uri;
    }
    
    public function getUri() {
        return $this->uri;
    }
    
    public function setName($name) {
        if(empty($name)) {
            throw new Exception("Name cannot be set empty!");
        }
        //$this->name = htmlentities($name, ENT_QUOTES, "UTF-8", false);
        $this->name = htmlspecialchars($name, ENT_QUOTES, "UTF-8", false);
    }
    
    public function getName() {
        return $this->name;
    }
    
    public function setJid($jid) {
        if(empty($jid)) {
            throw new Exception("JID cannot be set empty!");
        }
        $this->jid = $jid;
        list($node, $domain) = explode('@', $this->jid);
        $this->setNode($node);
        $this->setDomain($domain);  
    }
    
    public function getJid() {
        return $this->jid;
    }
    
    private function setNode($node) {
        if(empty($node)) {
            throw new Exception("Node cannot be set empty!");
        }
        //$this->node = htmlentities($node, ENT_QUOTES, "UTF-8", false);
        $this->node = htmlspecialchars($node, ENT_QUOTES, "UTF-8", false);
    }
    
    public function getNode() {
        return $this->node;
    }
    
    private function setDomain($domain) {
        if(empty($domain)) {
            throw new Exception("Domain cannot be set empty!");
        }
        $this->domain = $domain;
    }
    
    public function getDomain() {
        return $this->domain;
    }
    
    public function setEncodedPrivateKey($privateKey) {
        if(empty($privateKey)) {
            throw new Exception("PrivateKey cannot be set empty!");
        }
        $this->encodedPrivateKey = $privateKey;
    }
    
    public function getEncodedPrivateKey() {
        return $this->encodedPrivateKey;
    }
    
    public function setEncodedPublicKey($publicKey) {
        if(empty($publicKey)) {
            throw new Exception("PublicKey cannot be set empty!");
        }
        $this->encodedPublicKey = $publicKey;
    }
    
    public function getEncodedPublicKey() {
        return $this->encodedPublicKey;
    }
    
    /**
     * We should have input something similar to this in the method:
     * 
	 * <minimeuser>
	 *   <jid>tkoski@domain.com</jid>
	 *   <name>Tuomas Koski</name>
	 *   <uri>http://lobstermosnter.org/minime</uri>
	 *   <encoded-privatekey></encoded-privatekey>
	 *   <encoded-publickey></encoded-publickey>
	 *   <title>My timeline!</title>
 	 *   <subtitle>My timeline provided by minime mini system. Minimalic!</subtitle>
     *   <logo>http://media.buddycloud.com/channel/54x54/buddycloud.com/koski.png</logo>
	 * </minimeuser>
	 * 
	 * @author tkoski
	 * @return Minime_User 
	 */
    public static function buildFromRawXML($rawXML) {
        $dom = new DOMDocument();
        if(@$dom->loadXML($rawXML)) {
            return self::buildFromDom($dom);
        }
        throw new Exception("Invalid raw XML data provided!");
    }

    public static function buildFromDom(DOMDocument $dom) {

	    $minime_element = $dom->getElementsByTagName(self::ELEMENT_ROOT)->item(0);
	    if(!$minime_element) {
	        throw new Exception("Invalid XML! No minime root element found!");
	    }
	    
	    $user = new Minime_User();
	    $user->setUri($minime_element->getElementsByTagName(self::ELEMENT_URI)->item(0)->nodeValue);
	    $user->setJid($minime_element->getElementsByTagName(self::ELEMENT_JID)->item(0)->nodeValue);
	    $user->setName($minime_element->getElementsByTagName(self::ELEMENT_NAME)->item(0)->nodeValue);
	    $user->setEncodedPrivateKey($minime_element->getElementsByTagName(self::ELEMENT_ENCODEDPRIVATEKEY)->item(0)->nodeValue);
	    $user->setEncodedPublicKey($minime_element->getElementsByTagName(self::ELEMENT_ENCODEDPUBLICKEY)->item(0)->nodeValue);
	    $user->setTitle($minime_element->getElementsByTagName(self::ELEMENT_TITLE)->item(0)->nodeValue);
	    $user->setSubtitle($minime_element->getElementsByTagName(self::ELEMENT_SUBTITLE)->item(0)->nodeValue);
	    $user->setLogo($minime_element->getElementsByTagName(self::ELEMENT_LOGO)->item(0)->nodeValue);
	    return $user;
    }
    
    /**
     * @param array $array
     * @return Minime_User
     */
    public static function buildFromArray(Array $array) {
        $user = new Minime_User();
        $user->setUri($array['uri']);
        $user->setName($array['name']);
        $user->setJid($array['jid']);
        $user->setEncodedPrivateKey($array['privatekey']);
        $user->setEncodedPublicKey($array['publickey']);
        $user->setTitle($array['title']);
        $user->setSubtitle($array['subtitle']);
        $user->setLogo($array['logo']);
        return $user;
    }

    public function asXML() {
        $dom = new DOMDocument('1.0', 'UTF-8');
		$dom->formatOutput = true;
		
		$root_element = $dom->createElement(self::ELEMENT_ROOT);
		$uri_element = $dom->createElement(self::ELEMENT_URI, $this->getUri());
		$jid_element = $dom->createElement(self::ELEMENT_JID, $this->getJid());
		$name_element = $dom->createElement(self::ELEMENT_NAME, $this->getName());
		$encodedPrivateKey_element = $dom->createElement(self::ELEMENT_ENCODEDPRIVATEKEY, $this->getEncodedPrivateKey());
		$encodedPublicKey_element = $dom->createElement(self::ELEMENT_ENCODEDPUBLICKEY, $this->getEncodedPublicKey());
        $title_element = $dom->createElement(self::ELEMENT_TITLE, $this->getTitle());
		$subtitle_element = $dom->createElement(self::ELEMENT_SUBTITLE, $this->getSubtitle());
		$logo_element = $dom->createElement(self::ELEMENT_LOGO, $this->getLogo());
		
		$root_element->appendChild($uri_element);
		$root_element->appendChild($jid_element);
		$root_element->appendChild($name_element);
		$root_element->appendChild($encodedPrivateKey_element);
		$root_element->appendChild($encodedPublicKey_element);
		$root_element->appendChild($title_element);
		$root_element->appendChild($subtitle_element);
		$root_element->appendChild($logo_element);
		        
		$dom->appendChild($root_element);
		return $dom->saveXML();
    }
}